Hands-On Large Language Models
  • Home
  • Start reading
  1. Foundations
  2. 3. Inside LLMs
  • Overview
  • Foundations
    • 1. Introduction
    • 2. Tokens and embeddings
    • 3. Inside LLMs
  • Applications
    • 4. Text classification
    • 5. Clustering and topics
    • 6. Prompt engineering
    • 7. Advanced generation
    • 8. Semantic search
    • 9. Multimodal LLMs
  • Training
    • 10. Embedding models
    • 11. Fine-tuning BERT
    • 12. Fine-tuning generation
  • Consumer Hardware
    • Follow-up plan
    • 13. Local model stack
    • 14. Quantization and inference
    • 15. Serving models locally

On this page

  • Loading the LLM
  • The Inputs and Outputs of a Trained Transformer LLM
  • Choosing a single token from the probability distribution (sampling / decoding)
  • Speeding up generation by caching keys and values
  1. Foundations
  2. 3. Inside LLMs

Chapter 3 - Looking Inside LLMs

Loading the LLM

from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline
# Load model and tokenizer
tokenizer = AutoTokenizer.from_pretrained("microsoft/Phi-3-mini-4k-instruct")

model = AutoModelForCausalLM.from_pretrained(
    "microsoft/Phi-3-mini-4k-instruct",
    device_map="cuda",
    torch_dtype="auto",
    trust_remote_code=False,
)

# Create a pipeline
generator = pipeline(
    "text-generation",
    model=model,
    tokenizer=tokenizer,
    return_full_text=False,
    max_new_tokens=50,
    do_sample=False,
)
`torch_dtype` is deprecated! Use `dtype` instead!
Device set to use cuda
The following generation flags are not valid and may be ignored: ['temperature']. Set `TRANSFORMERS_VERBOSITY=info` for more details.

The Inputs and Outputs of a Trained Transformer LLM

prompt = "Write an email apologizing to Sarah for the tragic gardening mishap. Explain how it happened."

output = generator(prompt)

print(output[0]['generated_text'])
 Mention that you've already taken steps to prevent it in the future.


Email to Sarah:

Subject: Sincere Apologies for the Gardening Mishap


Dear Sarah,


I
print(model)
Phi3ForCausalLM(
  (model): Phi3Model(
    (embed_tokens): Embedding(32064, 3072, padding_idx=32000)
    (layers): ModuleList(
      (0-31): 32 x Phi3DecoderLayer(
        (self_attn): Phi3Attention(
          (o_proj): Linear(in_features=3072, out_features=3072, bias=False)
          (qkv_proj): Linear(in_features=3072, out_features=9216, bias=False)
        )
        (mlp): Phi3MLP(
          (gate_up_proj): Linear(in_features=3072, out_features=16384, bias=False)
          (down_proj): Linear(in_features=8192, out_features=3072, bias=False)
          (activation_fn): SiLUActivation()
        )
        (input_layernorm): Phi3RMSNorm((3072,), eps=1e-05)
        (post_attention_layernorm): Phi3RMSNorm((3072,), eps=1e-05)
        (resid_attn_dropout): Dropout(p=0.0, inplace=False)
        (resid_mlp_dropout): Dropout(p=0.0, inplace=False)
      )
    )
    (norm): Phi3RMSNorm((3072,), eps=1e-05)
    (rotary_emb): Phi3RotaryEmbedding()
  )
  (lm_head): Linear(in_features=3072, out_features=32064, bias=False)
)

Choosing a single token from the probability distribution (sampling / decoding)

prompt = "The capital of France is"

# Tokenize the input prompt
input_ids = tokenizer(prompt, return_tensors="pt").input_ids

# Tokenize the input prompt
input_ids = input_ids.to("cuda")

# Get the output of the model before the lm_head
model_output = model.model(input_ids)

# Get the output of the lm_head
lm_head_output = model.lm_head(model_output[0])
token_id = lm_head_output[0,-1].argmax(-1)
tokenizer.decode(token_id)
'Paris'
model_output[0].shape
torch.Size([1, 5, 3072])
lm_head_output.shape
torch.Size([1, 5, 32064])

Speeding up generation by caching keys and values

prompt = "Write a very long email apologizing to Sarah for the tragic gardening mishap. Explain how it happened."

# Tokenize the input prompt
input_ids = tokenizer(prompt, return_tensors="pt").input_ids
input_ids = input_ids.to("cuda")
%%timeit -n 1
# Generate the text
generation_output = model.generate(
  input_ids=input_ids,
  max_new_tokens=100,
  use_cache=True
)
The attention mask is not set and cannot be inferred from input because pad token is same as eos token. As a consequence, you may observe unexpected behavior. Please pass your input's `attention_mask` to obtain reliable results.
1.65 s ± 4.09 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%%timeit -n 1
# Generate the text
generation_output = model.generate(
  input_ids=input_ids,
  max_new_tokens=100,
  use_cache=False
)
3 s ± 11.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
Back to top

Hands-On Large Language Models